#ifndef XICT_DRIVER_UTILS_UTILS_ERROR_H
#define XICT_DRIVER_UTILS_UTILS_ERROR_H

#include <ctime>
#include <string>

namespace xict_driver {
    namespace utils {
        enum class ErrCodeType {
            INFO_CODE,      // 0x00 ~ 0x3F
            WARNING_CODE,   // 0x40 ~ 0x7F
            ERROR_CODE      // 0x80 ~ 0xBF
        };

        enum ErrCode {
            // Info
            ERRCODE_SUCCESS            = 0x00,   // 正常状态
            ERRCODE_IMU_DRIVER_NORMAL  = 0x01,   // IMU驱动正常
            ERRCODE_GNSS_DRIVER_NORMAL = 0x02,   // GNSS数据正常

            // Warning
            ERRCODE_IMU_DRIVER_RECONNECTION = 0x40,   // IMU驱动重连中
            ERRCODE_WHEEL_DATA_TIMEOUT      = 0x41,   // 轮速计数据超时
            ERRCODE_LIDAR_DATA_TIMEOUT = 0x42,   // 激光雷达数据超时
            ERRCODE_GNSS_DATA_TIMEOUT  = 0x43,   // GNSS数据超时

            // Error
            ERRCORE_START_BEFORE_INIT = 0x80,   // 在init()之前调用start()
            ERRCORE_NO_INPUT_PARAMS   = 0x81,   // 没有输入参数
            ERRCODE_IMU_DRIVER_ERROR  = 0x82,   // IMU驱动错误
            ERRCODE_GNSS_DRIVER_ERROR = 0x83    // GNSS驱动错误
        };

        /**
         * @brief 定位Error信息
         *
         */
        struct ErrorInfo {
            ErrCode error_code_;
            ErrCodeType error_code_type_;

            ErrorInfo() : error_code_(ErrCode::ERRCODE_SUCCESS) { }

            explicit ErrorInfo(const ErrCode& code) : error_code_(code) {
                if (error_code_ < 0x40) {
                    error_code_type_ = ErrCodeType::INFO_CODE;
                } else if (error_code_ < 0x80) {
                    error_code_type_ = ErrCodeType::WARNING_CODE;
                } else {
                    error_code_type_ = ErrCodeType::ERROR_CODE;
                }
            }

            std::string ToString() const {
                switch (error_code_) {
                // info

                // warning
                case ERRCODE_IMU_DRIVER_RECONNECTION:
                    return "[ErrorCode] IMU data timeout";
                case ERRCODE_WHEEL_DATA_TIMEOUT:
                    return "[ErrorCode] Wheel data timeout";

                // default
                default:
                    return "[ErrorCode] Success";
                }
            }
        };
    }   // namespace utils
}   // namespace xict_driver

#endif